package mechanism;

interface Callback {
	void increment();
}

// Very simple to just implement the interface:
class Callee1 implements Callback {
	private int i = 0;
	public void increment() {
		i++;
		System.out.println(i);
	}
}

//
class MyIncrement {
	void increment() {
		System.out.println("Other operation");
	}

	static void f(MyIncrement mi) {
		mi.increment();
	}
}

// If your class must implement increment() in
// some other way, you must use an inner class:
class Callee2 extends MyIncrement {
	private int i = 0;

	private void incr() {
		i++;
		System.out.println(i);
	}

	private class Closuer implements Callback {
		public void increment() {
			incr();
		}
	}

	Callback getCallbackReference() {
		return new Closuer();
	}
}

class Caller {
	private Callback callbackReference;
	Caller(Callback cbh) {
		callbackReference = cbh;
	}
	void go() {
		callbackReference.increment();
	}
}

class Callbacks {
	public static void main(String[] args) {
		Callee1 c1 = new Callee1();
		Callee2 c2 = new Callee2();
		MyIncrement.f(c2);
		
		Caller caller1 = new Caller(c1);
		Caller caller2 = new Caller(c2.getCallbackReference());
		caller1.go();
		caller1.go();
		caller2.go();
		caller2.go();
	}
}